package cfengMiddleware.server.rabbitmq.producer;

import cfengMiddleware.server.rabbitmq.entity.Student;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * @author Cfeng
 * @date 2022/9/15
 *
 * 基础模型的生产者
 */


@Slf4j
@Component
@RequiredArgsConstructor
public class BasicPublisher {

    private final ObjectMapper objectMapper;

    private final  RabbitTemplate rabbitTemplate;

    //配置项获取
    private final Environment environment;

    /**
     * 发送消息
     */
    public void sendMsg(String message) {
        //首先要判断消息是否为空
        if(!Strings.isNullOrEmpty(message)) {
            try {
                //传输数据格式JSON
                rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
                //指定消息模型的交换机
                rabbitTemplate.setExchange(Objects.requireNonNull(environment.getProperty("spring.rabbitmq.exchange-name")));
                //指定消息模型的路由
                rabbitTemplate.setRoutingKey(Objects.requireNonNull(environment.getProperty("spring.rabbitmq.route-name")));
                //消息以二进制字符流传输
                Message msg = MessageBuilder.withBody(objectMapper.writeValueAsBytes(message)).setDeliveryMode(MessageDeliveryMode.PERSISTENT).build();
                //RabbitMQ本身是异步通信，但是如果想要确保
                //转化发送消息
                rabbitTemplate.convertAndSend(msg);
                log.info("基本模型： 生产者发送消息: {}",message);
            } catch (Exception e) {
                log.error("基本消息模型 生产者 发送消息发生异常： {}", e.fillInStackTrace());
            }
        }
    }

    public void sendObjectMsg(Student student) {
        //首先选哟判断是否不为null
        if(!Objects.isNull(student)) {
            try {
                rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
                //消息的交换机和binding
                rabbitTemplate.setExchange(environment.getProperty("spring.rabbitmq.exchange-object-name"));
                rabbitTemplate.setRoutingKey(Objects.requireNonNull(environment.getProperty("spring.rabbitmq.route-object-name")));
                //发送消息
                rabbitTemplate.convertAndSend(student, message -> {
                    //获取消息属性
                    MessageProperties properties = message.getMessageProperties();
                    //持久化模式，PERSISTENT
                    properties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                    //设置消息的类型,消息头设置AbstractJavaTypeMapper的默认的类型
                    properties.setHeader(AbstractJavaTypeMapper.DEFAULT_KEY_CLASSID_FIELD_NAME,Student.class);
                    //返回配置后的消息
                    return message;
                });
                log.info("基本消息模型-生产者-发送对象类型消息： {}",student.toString());
            } catch (Exception e) {
                log.error("基本消费模型-生产者, 发送消息失败: {}", student.toString(),e.fillInStackTrace());
            }
        }
    }
}
